package com.itheima.service.impl;

import com.alibaba.dubbo.config.annotation.Service;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.itheima.constant.MessageConstant;
import com.itheima.dao.UserDao;
import com.itheima.entity.PageResult;
import com.itheima.pojo.CheckGroup;
import com.itheima.pojo.User;
import com.itheima.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 用户服务接口实现类
 * @author wangxin
 * @version 1.0
 */
@Service(interfaceClass = UserService.class)
@Transactional
public class UserServiceImpl implements UserService
{

    @Autowired
    private UserDao userDao;

    /**
     * 使用BCrypt对用户密码进行加密
     */
    public static BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();

    /**
     * 根据用户名查询数据用户信息
     * @param username
     * @return
     */
    @Override
    public User findByUserName(String username) {
        return userDao.findByUserName(username);
    }

    /**
     * 用户列表分页
     * @param currentPage
     * @param pageSize
     * @param queryString
     * @return
     */
    @Override
    public PageResult findPage(Integer currentPage, Integer pageSize, String queryString) {
        PageHelper.startPage(currentPage,pageSize);
        //2.需要分页的语句
        Page<User> userPage = userDao.selectByCondition(queryString);
        return new PageResult(userPage.getTotal(),userPage.getResult());
    }

    /**
     * 新增用户
     * @param user
     * @param roleIds
     */
    @Override
    public void add(User user, Integer[] roleIds) {
        //往检查组表新增一条记录
        userDao.add(user);
        //往检查组和检查项中间表写记录
        setRoleAndUser(user.getId(),roleIds);
    }

    /**
     * 根据用户id查询用户信息
     * @param userId
     * @return
     */
    @Override
    public User findById(Integer userId) {
        return userDao.findById(userId);
    }

    /**
     * 根据用户id查询角色ids
     * @param userId
     * @return
     */
    @Override
    public List<Integer> findRoleIdsByUserId(Integer userId) {
        return userDao.findRoleIdsByUserId(userId);
    }

    /**
     * 删除用户
     * @param id
     */
    @Override
    public void deleteById(Integer id) {
        //业务角度考虑
        //查询用户和角色表关系是否存在，存在则无法删除
        int count = userDao.findCountByUserId(id);
        if(count>0){
            throw new RuntimeException(MessageConstant.DELETE_ROLE_USER_FAIL);//一定要install
        }

        //以上关系都不存在，则可以删除
        userDao.deleteById(id);
    }

    /**
     * 编辑用户
     * @param user
     * @param roleIds
     */
    @Override
    public void edit(User user, Integer[] roleIds) {
        //更新用户表 update 语句
        userDao.edit(user);
        //先删除用户关联的角色记录 （中间表）
        userDao.deleteAssociation(user.getId());
        // 重新建立关联关系（插入中间表）
        setRoleAndUser(user.getId(),roleIds);
    }

    /**
     * 修改用户密码
     * @param map
     */
    @Override
    public void changePassword(Map map) {
        //获取用户名，判断用户是否存在
        String username =(String) map.get("username");
        User user = userDao.findByUserName(username);
        if (user == null){
            throw new RuntimeException(MessageConstant.USER_NONE);
        }
        //判断密码是否一致
        boolean isSame = encoder.matches((String) map.get("oldPassword"), user.getPassword());
        if (!isSame){
            throw new RuntimeException(MessageConstant.PASSWORD_ERROR);
        }
        //旧密码一致，则修改密码
        //对新密码进行加密
        String newPassword = encoder.encode((String) map.get("newPassword"));
        user.setPassword(newPassword);
        userDao.edit(user);
    }

    /**
     * 往检查组和检查项中间表写记录
     * @param id
     * @param roleIds
     */
    private void setRoleAndUser(Integer id, Integer[] roleIds) {
        if(roleIds != null && roleIds.length> 0){
            for (Integer roleId : roleIds) {
                //为了方便测试传入map对象
                Map<String,Integer> map = new HashMap<>();
                map.put("userId",id);
                map.put("roleId",roleId);
                userDao.setRoleAndUser(map);
            }
        }
    }
}
